
package com.bening.smsapp.parser.thread;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.commons.pool.impl.GenericObjectPool;

import com.bening.smsapp.bootstrap.BootConfigParameters;

public class ThreadPool extends GenericObjectPool {
   /**
    * Logger for this class
    */
   private static final Log log = LogFactory.getLog(ThreadPool.class);
   private static BootConfigParameters bootParam = BootConfigParameters.getInstance();
   /**
    * Constructor when there is no configuration available. Please refer
    * commons-pooling for more details on the configuration parameters.
    * @param objFactory - The factory to be used for thread creation.
    */
   public ThreadPool(ThreadObjectFactory objFactory) {
      super(objFactory);
      this.setMaxIdle(bootParam.getThreadIdle()); // maximum idle threads
      this.setMaxActive(bootParam.getThreadWorker()); // maximum active threads.
      //this.setMinEvictableIdleTimeMillis(10000); //Evictor runs every 30 secs.
      this.setTestOnBorrow(false); // check if the thread is still valid
      this.setMaxWait(bootParam.getThreadWait()); // 10 second wait when threads are not available.
   }

   /**
    * Constructor to be used when there is a configuration available.
    * @param objFactory -
    *           The factory to be used for thread creation..
    * @param config -
    *           This could be created by loading a properties file.
    */
   public ThreadPool(ThreadObjectFactory objFactory,
         GenericObjectPool.Config config) {
      super(objFactory, config);
   }

   /* (non-Javadoc)
    * @see org.apache.commons.pool.ObjectPool#borrowObject()
    */
   public Object borrowObject() throws Exception {
      return super.borrowObject();
   }

   /* (non-Javadoc)
    * @see org.apache.commons.pool.ObjectPool#returnObject(java.lang.Object)
    */
   public void returnObject(Object obj) throws Exception {
      super.returnObject(obj);
   }

   /**
    * borrowObjects - Helper method, use this carefully since this could be
    * a blocking call when the threads requested may not be avialable based
    * on the configuration being used.
    * @param num
    * @return WorkerThread[]
    */
   public synchronized WorkerThread[] borrowObjects(int num) {
      WorkerThread[] rtArr = new WorkerThread[num];
      for (int i = 0; i < num; i++) {
         WorkerThread rt; 
         try {
            rt = (WorkerThread) borrowObject();
            rtArr[i] = rt;
         } catch (Exception e) {
            log.error(" borrowObjects failed.. ", e);
         }
      }
      return rtArr;
   }

}